﻿%token 'pop_top'
%token 'rot_two'
%token 'rot_three'
%token 'dup_top'
%token 'dup_top_two'
%token 'rot_four'
%token 'nop'
%token 'unary_positive'
%token 'unary_negative'
%token 'unary_not'
%token 'unary_invert'
%token 'binary_matrix_multiply'
%token 'inplace_matrix_multiply'
%token 'binary_power'
%token 'binary_multiply'
%token 'binary_modulo'
%token 'binary_add'
%token 'binary_subtract'
%token 'binary_subscr'
%token 'binary_floor_divide'
%token 'binary_true_divide'
%token 'inplace_floor_divide'
%token 'inplace_true_divide'
%token 'reraise'
%token 'with_except_start'
%token 'get_aiter'
%token 'get_anext'
%token 'before_async_with'
%token 'end_async_for'
%token 'inplace_add'
%token 'inplace_subtract'
%token 'inplace_multiply'
%token 'inplace_modulo'
%token 'store_subscr'
%token 'delete_subscr'
%token 'binary_lshift'
%token 'binary_rshift'
%token 'binary_and'
%token 'binary_xor'
%token 'binary_or'
%token 'inplace_power'
%token 'get_iter'
%token 'get_yield_from_iter'
%token 'print_expr'
%token 'load_build_class'
%token 'yield_from'
%token 'get_awaitable'
%token 'load_assertion_error'
%token 'inplace_lshift'
%token 'inplace_rshift'
%token 'inplace_and'
%token 'inplace_xor'
%token 'inplace_or'
%token 'list_to_tuple'
%token 'return_value'
%token 'import_star'
%token 'setup_annotations'
%token 'yield_value'
%token 'pop_block'
%token 'pop_except'
%token 'store_name'
%token 'delete_name'
%token 'unpack_sequence'
%token 'for_iter'
%token 'unpack_ex'
%token 'store_attr'
%token 'delete_attr'
%token 'store_global'
%token 'delete_global'
%token 'load_const'
%token 'load_name'
%token 'build_tuple'
%token 'build_list'
%token 'build_set'
%token 'build_map'
%token 'load_attr'
%token 'compare_op'
%token 'import_name'
%token 'import_from'
%token 'jump_forward'
%token 'jump_if_false_or_pop'
%token 'jump_if_true_or_pop'
%token 'jump_absolute'
%token 'pop_jump_if_false'
%token 'pop_jump_if_true'
%token 'load_global'
%token 'is_op'
%token 'contains_op'
%token 'jump_if_not_exc_match'
%token 'setup_finally'
%token 'load_fast'
%token 'store_fast'
%token 'delete_fast'
%token 'raise_varargs'
%token 'call_function'
%token 'make_function'
%token 'build_slice'
%token 'load_closure'
%token 'load_deref'
%token 'store_deref'
%token 'delete_deref'
%token 'call_function_kw'
%token 'call_function_ex'
%token 'setup_with'
%token 'list_append'
%token 'set_add'
%token 'map_add'
%token 'load_classderef'
%token 'setup_async_with'
%token 'format_value'
%token 'build_const_key_map'
%token 'build_string'
%token 'load_method'
%token 'call_method'
%token 'list_extend'
%token 'set_update'
%token 'dict_merge'
%token 'dict_update'

%token 'None'
%token 'False'
%token 'True'
%token 'StopIteration'
%token 'Ellipsis'

%token Identifier ("identifier") : Identifier
%token Int32Literal ("int32 literal") : Int32Literal
%token IntegerLiteral ("integer literal") : IntegerLiteral
%token FloatLiteral ("float literal") : FloatLiteral
%token ComplexLiteral ("complex literal") : ComplexLiteral
%token StringLiteral ("string literal") : StringLiteral
%token ByteStringLiteral ("byte string literal") : ByteStringLiteral

%token '('
%token ')'
%token 'f{'
%token '}'
%token ','

%token '=='
%token '!='
%token '<'
%token '<='
%token '>'
%token '>='

Identifier = (name : string)
Int32Literal = (value : int32, isHexadecimal : bool?)
NonNegativeInt32Literal = (value : int32*, isHexadecimal : bool?)
PositiveInt32Literal = (value : int32+, isHexadecimal : bool?)
IntegerLiteral = (value : System.Numeric.BigInteger, isHexadecimal : bool?)
FloatLiteral = (value : float64)
ComplexLiteral = (value : System.Numeric.Complex)
StringLiteral = (value : string, isDoubleQuoted : bool?, isRaw : bool?, isLong : bool?)
ByteStringLiteral = (value : [byte], isDoubleQuoted : bool?, isRaw : bool?, isLong : bool?)
TupleLiteral = (items : [LiteralValue])
FrozenSetLiteral = (items : [LiteralValue])

LiteralValue:
    None
    False
    True
    StopIteration
    Ellipsis
    Int32 (value : Int32Literal)
    Integer (value : IntegerLiteral)
    Float (value : FloatLiteral)
    Complex (value : ComplexLiteral)
    String (value : StringLiteral)
    ByteString (value : ByteStringLiteral)
    Tuple (value : TupleLiteral)
    FrozenSet (value : FrozenSetLiteral)
    CodeBlock (name : Identifier)

CompareOp:
    EqualTo
    NotEqualTo
    LessThan
    LessEqual
    GreaterThan
    GreaterEqual

Instruction:
    PopTop
    RotTwo
    RotThree
    DupTop
    DupTopTwo
    RotFour
    Nop
    UnaryPositive
    UnaryNegative
    UnaryNot
    UnaryInvert
    BinaryMatrixMultiply
    InplaceMatrixMultiply
    BinaryPower
    BinaryMultiply
    BinaryModulo
    BinaryAdd
    BinarySubtract
    BinarySubscr
    BinaryFloorDivide
    BinaryTrueDivide
    InplaceFloorDivide
    InplaceTrueDivide
    Reraise
    WithExceptStart
    GetAiter
    GetAnext
    BeforeAsyncWith
    EndAsyncFor
    InplaceAdd
    InplaceSubtract
    InplaceMultiply
    InplaceModulo
    StoreSubscr
    DeleteSubscr
    BinaryLshift
    BinaryRshift
    BinaryAnd
    BinaryXor
    BinaryOr
    InplacePower
    GetIter
    GetYieldFromIter
    PrintExpr
    LoadBuildClass
    YieldFrom
    GetAwaitable
    LoadAssertionError
    InplaceLshift
    InplaceRshift
    InplaceAnd
    InplaceXor
    InplaceOr
    ListToTuple
    ReturnValue
    ImportStar
    SetupAnnotations
    YieldValue
    PopBlock
    PopExcept
    StoreName (name : Identifier)
    DeleteName (name : Identifier)
    UnpackSequence (length : NonNegativeInt32Literal)
    ForIter (cleanup : Identifier)
    UnpackEx (value : NonNegativeInt32Literal)
    StoreAttr (attribute : Identifier)
    DeleteAttr (attribute : Identifier)
    StoreGlobal (name : Identifier)
    DeleteGlobal (name : Identifier)
    LoadConst (value : LiteralValue)
    LoadName (name : Identifier)
    BuildTuple (count : NonNegativeInt32Literal)
    BuildList (count : NonNegativeInt32Literal)
    BuildSet (count : NonNegativeInt32Literal)
    BuildMap (count : NonNegativeInt32Literal)
    LoadAttr (attribute : Identifier)
    CompareOp (op : CompareOp)
    ImportName (name : Identifier)
    ImportFrom (name : Identifier)
    JumpForward (target : Identifier)
    JumpIfFalseOrPop (target : Identifier)
    JumpIfTrueOrPop (target : Identifier)
    JumpAbsolute (target : Identifier)
    PopJumpIfFalse (target : Identifier)
    PopJumpIfTrue (target : Identifier)
    LoadGlobal (name : Identifier)
    IsOp (reversed : bool)
    ContainsOp (reversed : bool)
    JumpIfNotExcMatch (target : Identifier)
    SetupFinally (finallyBody : Identifier)
    LoadFast (target : Identifier)
    StoreFast (target : Identifier)
    DeleteFast (target : Identifier)
    RaiseVarargs (count : NonNegativeInt32Literal)
    CallFunction (count : NonNegativeInt32Literal)
    MakeFunction (flags : NonNegativeInt32Literal)
    BuildSlice (count : NonNegativeInt32Literal)
    LoadClosure (name : Identifier)
    LoadDeref (name : Identifier)
    StoreDeref (name : Identifier)
    DeleteDeref (name : Identifier)
    CallFunctionKw (count : NonNegativeInt32Literal)
    CallFunctionEx (hasKeywords : bool)
    SetupWith (finallyBody : Identifier)
    ListAppend (depth : PositiveInt32Literal)
    SetAdd (depth : PositiveInt32Literal)
    MapAdd (depth : PositiveInt32Literal)
    LoadClassderef (name : Identifier)
    SetupAsyncWith (finallyBody : Identifier)
    FormatValue (flags : NonNegativeInt32Literal)
    BuildConstKeyMap (count : NonNegativeInt32Literal)
    BuildString (count : NonNegativeInt32Literal)
    LoadMethod (name : Identifier)
    CallMethod (count : NonNegativeInt32Literal)
    ListExtend (depth : PositiveInt32Literal)
    SetUpdate (depth : PositiveInt32Literal)
    DictMerge (depth : PositiveInt32Literal)
    DictUpdate (depth : PositiveInt32Literal)

%%

LiteralValue as LiteralValue:
    'None' => LiteralValue.NewNone(@@)
    'False' => LiteralValue.NewFalse(@@)
    'True' => LiteralValue.NewTrue(@@)
    'StopIteration' => LiteralValue.NewStopIteration(@@)
    'Ellipsis' => LiteralValue.NewEllipsis(@@)
    Int32Literal => LiteralValue.NewInt32($1, @@)
    IntegerLiteral => LiteralValue.NewInteger($1, @@)
    FloatLiteral => LiteralValue.NewFloat($1, @@)
    ComplexLiteral => LiteralValue.NewComplex($1, @@)
    StringLiteral => LiteralValue.NewString($1, @@)
    ByteStringLiteral => LiteralValue.NewByteString($1, @@)
    '(' ')' => LiteralValue.NewTuple(TupleLiteral.New(default([LiteralValue]), @@), @@)
    '(' LiteralValue ',' ')' => LiteralValue.NewTuple(TupleLiteral.New(Sequence.Create($2), @@), @@)
    '(' LiteralValue ',' LiteralValue %+ ',' ','? ')' => LiteralValue.NewTuple(TupleLiteral.New(Sequence.Prepend($2, $4), @@), @@)
    'f{' '}' => LiteralValue.NewFrozenSet(FrozenSetLiteral.New(default([LiteralValue]), @@), @@)
    'f{' LiteralValue %+ ',' ','? '}' => LiteralValue.NewFrozenSet($2, @@)
    Identifier => LiteralValue.NewCodeBlock($1, @@)

CompareOp as CompareOp:
    '==' => CompareOp.NewEqualTo(@@)
    '!=' => CompareOp.NewNotEqualTo(@@)
    '<' => CompareOp.NewLessThan(@@)
    '<=' => CompareOp.NewLessEqual(@@)
    '>' => CompareOp.NewGreaterThan(@@)
    '>=' => CompareOp.NewGreaterEqual(@@)

Instruction as Instruction:
    'pop_top' => Instruction.NewPopTop(@@)
    'rot_two' => Instruction.NewRotTwo(@@)
    'rot_three' => Instruction.NewRotThree(@@)
    'dup_top' => Instruction.NewDupTop(@@)
    'dup_top_two' => Instruction.NewDupTopTwo(@@)
    'rot_four' => Instruction.NewRotFour(@@)
    'nop' => Instruction.NewNop(@@)
    'unary_positive' => Instruction.NewUnaryPositive(@@)
    'unary_negative' => Instruction.NewUnaryNegative(@@)
    'unary_not' => Instruction.NewUnaryNot(@@)
    'unary_invert' => Instruction.NewUnaryInvert(@@)
    'binary_matrix_multiply' => Instruction.NewBinaryMatrixMultiply(@@)
    'inplace_matrix_multiply' => Instruction.NewInplaceMatrixMultiply(@@)
    'binary_power' => Instruction.NewBinaryPower(@@)
    'binary_multiply' => Instruction.NewBinaryMultiply(@@)
    'binary_modulo' => Instruction.NewBinaryModulo(@@)
    'binary_add' => Instruction.NewBinaryAdd(@@)
    'binary_subtract' => Instruction.NewBinarySubtract(@@)
    'binary_subscr' => Instruction.NewBinarySubscr(@@)
    'binary_floor_divide' => Instruction.NewBinaryFloorDivide(@@)
    'binary_true_divide' => Instruction.NewBinaryTrueDivide(@@)
    'inplace_floor_divide' => Instruction.NewInplaceFloorDivide(@@)
    'inplace_true_divide' => Instruction.NewInplaceTrueDivide(@@)
    'reraise' => Instruction.NewReraise(@@)
    'with_except_start' => Instruction.NewWithExceptStart(@@)
    'get_aiter' => Instruction.NewGetAiter(@@)
    'get_anext' => Instruction.NewGetAnext(@@)
    'before_async_with' => Instruction.NewBeforeAsyncWith(@@)
    'end_async_for' => Instruction.NewEndAsyncFor(@@)
    'inplace_add' => Instruction.NewInplaceAdd(@@)
    'inplace_subtract' => Instruction.NewInplaceSubtract(@@)
    'inplace_multiply' => Instruction.NewInplaceMultiply(@@)
    'inplace_modulo' => Instruction.NewInplaceModulo(@@)
    'store_subscr' => Instruction.NewStoreSubscr(@@)
    'delete_subscr' => Instruction.NewDeleteSubscr(@@)
    'binary_lshift' => Instruction.NewBinaryLshift(@@)
    'binary_rshift' => Instruction.NewBinaryRshift(@@)
    'binary_and' => Instruction.NewBinaryAnd(@@)
    'binary_xor' => Instruction.NewBinaryXor(@@)
    'binary_or' => Instruction.NewBinaryOr(@@)
    'inplace_power' => Instruction.NewInplacePower(@@)
    'get_iter' => Instruction.NewGetIter(@@)
    'get_yield_from_iter' => Instruction.NewGetYieldFromIter(@@)
    'print_expr' => Instruction.NewPrintExpr(@@)
    'load_build_class' => Instruction.NewLoadBuildClass(@@)
    'yield_from' => Instruction.NewYieldFrom(@@)
    'get_awaitable' => Instruction.NewGetAwaitable(@@)
    'load_assertion_error' => Instruction.NewLoadAssertionError(@@)
    'inplace_lshift' => Instruction.NewInplaceLshift(@@)
    'inplace_rshift' => Instruction.NewInplaceRshift(@@)
    'inplace_and' => Instruction.NewInplaceAnd(@@)
    'inplace_xor' => Instruction.NewInplaceXor(@@)
    'inplace_or' => Instruction.NewInplaceOr(@@)
    'list_to_tuple' => Instruction.NewListToTuple(@@)
    'return_value' => Instruction.NewReturnValue(@@)
    'import_star' => Instruction.NewImportStar(@@)
    'setup_annotations' => Instruction.NewSetupAnnotations(@@)
    'yield_value' => Instruction.NewYieldValue(@@)
    'pop_block' => Instruction.NewPopBlock(@@)
    'pop_except' => Instruction.NewPopExcept(@@)
    'store_name' Identifier => Instruction.NewStoreName($2, @@)
    'delete_name' Identifier => Instruction.NewDeleteName($2, @@)
    'unpack_sequence' NonNegativeInt32Literal => Instruction.NewUnpackSequence($2, @@)
    'for_iter' Identifier => Instruction.NewForIter($2, @@)
    'unpack_ex' NonNegativeInt32Literal => Instruction.NewUnpackEx($2, @@)
    'store_attr' Identifier => Instruction.NewStoreAttr($2, @@)
    'delete_attr' Identifier => Instruction.NewDeleteAttr($2, @@)
    'store_global' Identifier => Instruction.NewStoreGlobal($2, @@)
    'delete_global' Identifier => Instruction.NewDeleteGlobal($2, @@)
    'load_const' LiteralValue => Instruction.NewLoadConst($2, @@)
    'load_name' Identifier => Instruction.NewLoadName($2, @@)
    'build_tuple' NonNegativeInt32Literal => Instruction.NewBuildTuple($2, @@)
    'build_list' NonNegativeInt32Literal => Instruction.NewBuildList($2, @@)
    'build_set' NonNegativeInt32Literal => Instruction.NewBuildSet($2, @@)
    'build_map' NonNegativeInt32Literal => Instruction.NewBuildMap($2, @@)
    'load_attr' Identifier => Instruction.NewLoadAttr($2, @@)
    'compare_op' CompareOp => Instruction.NewCompareOp($2, @@)
    'import_name' Identifier => Instruction.NewImportName($2, @@)
    'import_from' Identifier => Instruction.NewImportFrom($2, @@)
    'jump_forward' Identifier => Instruction.NewJumpForward($2, @@)
    'jump_if_false_or_pop' Identifier => Instruction.NewJumpIfFalseOrPop($2, @@)
    'jump_if_true_or_pop' Identifier => Instruction.NewJumpIfTrueOrPop($2, @@)
    'jump_absolute' Identifier => Instruction.NewJumpAbsolute($2, @@)
    'pop_jump_if_false' Identifier => Instruction.NewPopJumpIfFalse($2, @@)
    'pop_jump_if_true' Identifier => Instruction.NewPopJumpIfTrue($2, @@)
    'load_global' Identifier => Instruction.NewLoadGlobal($2, @@)
    'is_op' 'False' => Instruction.NewIsOp(False, @@)
    'is_op' 'True' => Instruction.NewIsOp(True, @@)
    'contains_op' 'False' => Instruction.NewContainsOp(False, @@)
    'contains_op' 'True' => Instruction.NewContainsOp(True, @@)
    'jump_if_not_exc_match' Identifier => Instruction.NewJumpIfNotExcMatch($2, @@)
    'setup_finally' Identifier => Instruction.NewSetupFinally($2, @@)
    'load_fast' Identifier => Instruction.NewLoadFast($2, @@)
    'store_fast' Identifier => Instruction.NewStoreFast($2, @@)
    'delete_fast' Identifier => Instruction.NewDeleteFast($2, @@)
    'raise_varargs' NonNegativeInt32Literal => Instruction.NewRaiseVarargs($2, @@)
    'call_function' NonNegativeInt32Literal => Instruction.NewCallFunction($2, @@)
    'make_function' NonNegativeInt32Literal => Instruction.NewMakeFunction($2, @@)
    'build_slice' NonNegativeInt32Literal => Instruction.NewBuildSlice($2, @@)
    'load_closure' Identifier => Instruction.NewLoadClosure($2, @@)
    'load_deref' Identifier => Instruction.NewLoadDeref($2, @@)
    'store_deref' Identifier => Instruction.NewStoreDeref($2, @@)
    'delete_deref' Identifier => Instruction.NewDeleteDeref($2, @@)
    'call_function_kw' NonNegativeInt32Literal => Instruction.NewCallFunctionKw($2, @@)
    'call_function_ex' 'False' => Instruction.NewCallFunctionEx(False, @@)
    'call_function_ex' 'True' => Instruction.NewCallFunctionEx(True, @@)
    'setup_with' Identifier => Instruction.NewSetupWith($2, @@)
    'list_append' PositiveInt32Literal => Instruction.NewListAppend($2, @@)
    'set_add' PositiveInt32Literal => Instruction.NewSetAdd($2, @@)
    'map_add' PositiveInt32Literal => Instruction.NewMapAdd($2, @@)
    'load_classderef' Identifier => Instruction.NewLoadClassderef($2, @@)
    'setup_async_with' Identifier => Instruction.NewSetupAsyncWith($2, @@)
    'format_value' NonNegativeInt32Literal => Instruction.NewFormatValue($2, @@)
    'build_const_key_map' NonNegativeInt32Literal => Instruction.NewBuildConstKeyMap($2, @@)
    'build_string' NonNegativeInt32Literal => Instruction.NewBuildString($2, @@)
    'load_method' Identifier => Instruction.NewLoadMethod($2, @@)
    'call_method' NonNegativeInt32Literal => Instruction.NewCallMethod($2, @@)
    'list_extend' PositiveInt32Literal => Instruction.NewListExtend($2, @@)
    'set_update' PositiveInt32Literal => Instruction.NewSetUpdate($2, @@)
    'dict_merge' PositiveInt32Literal => Instruction.NewDictMerge($2, @@)
    'dict_update' PositiveInt32Literal => Instruction.NewDictUpdate($2, @@)
